﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace umbraco.DataServices.Linq.Schema
{
    public class LegacySchema : ISchema
    {
        public XElement GetParent(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return element.Parent;
        }

        public IEnumerable<XElement> GetAncestors(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return element.Ancestors("node");
        }

        public IEnumerable<XElement> GetAncestorsNamed(XElement element, IEnumerable<string> aliases) {
            if (element == null)
                throw new ArgumentNullException("element");
            if (aliases == null)
                throw new ArgumentNullException("aliases");
            return GetAncestors(element).Where(p => aliases.Contains(GetDocumentType(p)));
        }

        public IEnumerable<XElement> GetChildren(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return element.Elements("node");
        }

        public IEnumerable<XElement> GetChildrenNamed(XElement element, IEnumerable<string> aliases) {
            if (element == null)
                throw new ArgumentNullException("element");
            if (aliases == null)
                throw new ArgumentNullException("aliases");
            return GetChildren(element).Where(p => aliases.Contains(GetDocumentType(p)));
        }

        public IEnumerable<XElement> GetDescendants(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return element.Descendants("node");
        }

        public IEnumerable<XElement> GetDescendantsNamed(XElement element, IEnumerable<string> aliases) {
            if (element == null)
                throw new ArgumentNullException("element");
            if (aliases == null)
                throw new ArgumentNullException("aliases");
            return GetDescendants(element).Where(p => aliases.Contains(GetDocumentType(p)));
        }

        public IEnumerable<XElement> GetSibblings(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            var parent = element.Parent;
            if (parent == null)
                return null;
            return parent.Elements("node").Where(p => p != element); //Don't Include Current Element
        }

        public IEnumerable<XElement> GetSibblingsNamed(XElement element, IEnumerable<string> aliases) {
            if (element == null)
                throw new ArgumentNullException("element");
            if (aliases == null)
                throw new ArgumentNullException("aliases");
            return GetSibblings(element).Where(p => aliases.Contains(GetDocumentType(p)));
        }

        public IEnumerable<KeyValuePair<string,string>> GetProperties(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return element.Elements("data").Select(p => new KeyValuePair<string, string>((string)p.Attribute("alias"), p.Value));
        }

        public string GetProperty(XElement element, string alias) {
            if (element == null)
                throw new ArgumentNullException("element");
            var property = element.Elements("data").FirstOrDefault(p => p.HasAliasOf(alias));
            if (property == null)
                return null; //Property Not Found
            if (string.IsNullOrEmpty(property.Value))
                return string.Empty;
            return property.Value;
        }

        public int GetId(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("id");
        }

        public int GetParentId(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("parentID");
        }

        public int GetLevel(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("level");
        }

        public int GetWriterId(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("writerID");
        }

        public int GetCreatorId(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("creatorID");
        }

        public int GetTemplateId(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("template");
        }

        public int GetSortOrder(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("sortOrder");
        }

        public DateTime GetCreateDate(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (DateTime)element.Attribute("createDate");
        }

        public DateTime GetUpdateDate(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (DateTime)element.Attribute("updateDate");
        }

        public string GetTitle(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (string)element.Attribute("nodeName");
        }

        public string GetUrlName(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (string)element.Attribute("urlName");
        }

        public int GetDocumentTypeId(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (int)element.Attribute("nodeType");
        }

        public string GetDocumentType(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (string)element.Attribute("nodeTypeAlias");
        }

        public string GetWriterName(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (string)element.Attribute("writerName");
        }

        public string GetCreatorName(XElement element) {
            if (element == null)
                throw new ArgumentNullException("element");
            return (string)element.Attribute("creatorName");
        }

    }
}
